import json
import os
from datetime import datetime, timedelta

import jwt
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.exceptions import ObjectDoesNotExist
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from jwt import ExpiredSignatureError, DecodeError
from rest_framework.decorators import api_view
from rest_framework.exceptions import ValidationError
from rest_framework_jwt.settings import api_settings
from rest_framework.response import Response

from car.models import Car
from car.seriallzers import  CarSerializer
from user.TopicRecommender import TopicRecommender
from user.models import User, Topic, Comment
from user.redis import RedisUtils
from user.serializers import UserSerializer, TopicSerializer, HotSearchSerializer, TopiccommentSerializer, \
    TopicSerializer_2, UserSerializer2
from django.db.models import Q

from user.utls.utls import get_top_liked_users

jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

@api_view(['POST'])
def hotView(request):
    redis = RedisUtils()
    hot_search_data = redis.zRevRangeWithScores()
    # 将数据转换为序列化器需要的格式
    hot_search_list = [{'keyword': k, 'score': s} for k, s in hot_search_data]
    serializer = HotSearchSerializer(hot_search_list, many=True)
    return Response({'hot_search': serializer.data})


@api_view(['POST'])
def upload_avatar(request):
    try:
    # 从请求数据中获取 token
        token = request.data.get('token')
        if token:
            decoded_token = jwt.decode(token, options={"verify_signature": False})  # 解码JWT token
            user_id = decoded_token.get('user_id')  # 提取用户ID
            user = User.objects.get(pk=user_id)

            # 检查用户是否已经有头像，如果有，则先删除旧头像
            if user.avatar:
                old_avatar_path = user.avatar.path
                os.remove(old_avatar_path)
                user.avatar.delete()
            # 保存新头像，并重命名
            avatar = request.FILES['avatar']
            print(avatar)
            username = user.username
            now = datetime.now()
            filename = f'{username}_{now.strftime("%Y%m%d")}.{avatar.name.split(".")[-1]}'  # 拼接新文件名
            user.avatar.save(filename, avatar)
            # 返回成功响应
            avatar_url = user.avatar.url
            return JsonResponse({'message': '头像上传成功', 'avatar_url': avatar_url})
        else:
            return JsonResponse({'message': '未提供有效的 token'})
    except Exception as e:
        return JsonResponse({'message': str(e)})

@api_view(['POST'])
def usermsgView(request):
    if 'token' in request.data:
        token = request.data['token']
        try:
            decoded_token = jwt.decode(token, options={"verify_signature": False})  # 解码JWT token
            user_id = decoded_token.get('user_id')  # 提取用户ID
            user = User.objects.get(pk=user_id)
            # 查询用户的收藏话题和关注的用户
            usertopics = Topic.objects.filter(publisher=user_id)
            collected_topics = user.collect.all()
            concerned_users = user.concern.all()
            print(concerned_users)
            # 序列化用户及其收藏话题和关注的用户
            user_serializer = UserSerializer(user)
            collected_topics_serializer = TopicSerializer(collected_topics, many=True)  # 假设您已定义了 TopicSerializer
            usertopics_serializer = TopicSerializer(usertopics, many=True)  # 假设您已定义了 TopicSerializer
            concerned_users_serializer = UserSerializer2(concerned_users, many=True)
            # 返回用户数据及其收藏话题和关注的用户
            return Response({
                'user': user_serializer.data,
                'collected_topics': collected_topics_serializer.data,
                'concerned_users': concerned_users_serializer.data,
                'usertopics': usertopics_serializer.data,
            })
        except jwt.ExpiredSignatureError:
            return Response({'error': 'Token已过期'}, status=400)
        except jwt.DecodeError:
            return Response({'error': '无法解析Token'}, status=400)
    else:
        return Response({'error': '未找到token字段'}, status=400)

@api_view(['POST'])
def topicView(request):
    authorization_header = request.headers.get('Authorization')
    if authorization_header:
        token = authorization_header.split(' ')[1]  # 获取 Bearer 后的 token
        # 进行 token 验证和处理
        if token != None:
            # 获取分页参数
            page = int(request.data.get('page', 1))  # 默认为第一页
            page_size = int(request.data.get('page_size', 10))  # 默认每页显示 10 条数据
            # 定义查询集
            queryset = Topic.objects.all().order_by('-publish_time')
            # 手动进行分页
            start_index = (page - 1) * page_size
            end_index = start_index + page_size
            paginated_data = queryset[start_index:end_index]

            # 实例化序列化器并序列化分页后的结果
            serializer = TopicSerializer(paginated_data, many=True)

            return Response({'data':serializer.data,'total':len(queryset)})
        else:
            return Response({'error': '非法token'}, status=400)
    else:
        return Response({'error': '未找到token字段'}, status=400)

@api_view(['POST'])
def user_concern_topicView(request):
    try:
        authorization_header = request.META.get('HTTP_AUTHORIZATION')
        if authorization_header:
            token = authorization_header.split(' ')[1]
            decoded_token = jwt.decode(token, options={"verify_signature": False})
            user_id = decoded_token.get('user_id')  # 提取用户ID
            # 进行 token 验证和处理
            if token != None:
                # 定义查询集
                concerned_users_with_topics = User.objects.filter(user_concern__pk=user_id) \
                    .prefetch_related('topic_set')

                # 构建话题列表，包含所有关注用户发布的所有话题
                topics = [topic for user in concerned_users_with_topics for topic in user.topic_set.all()]
                # 对查询结果进行分页、排序等操作可以在这里添加
                # 序列化话题数据
                topics_list = TopicSerializer(topics, many=True)
                # 实例化序列化器并序列化分页后的结果
                return Response({'data': topics_list.data})
            else:
                return Response({'error': '非法token'}, status=400)
        else:
            return Response({'error': '未找到token字段'}, status=400)
    except DecodeError:
        return Response({'error': 'Token解码失败'}, status=400)
    except ObjectDoesNotExist:
        return Response({'error': '未找到对象'}, status=404)
    except Exception as e:
        return Response({'error': str(e)}, status=500)



@api_view(['POST'])
def userpostView(request):
    if 'token' in request.data:
        token = request.data['token']
        try:
            decoded_token = jwt.decode(token, options={"verify_signature": False})  # 解码JWT token
            user_id = decoded_token.get('user_id')  # 提取用户ID
            topic = Topic.objects.get(publisher=user_id)
            serializer = TopicSerializer(topic)
            return Response({'topic': serializer.data})
        except jwt.ExpiredSignatureError:
            return Response({'msg': 'Token已过期'}, status=400)
        except jwt.DecodeError:
            return Response({'msg': '无法解析Token'}, status=400)
    else:
        return Response({'msg': '未找到token字段'}, status=400)


@api_view(['POST'])
def loginView(request):
    username = request.data.get('username')  # 使用 request.data 获取 POST 数据
    password = request.data.get('password')
    user = User.objects.get(username=username)
    if user is not None:
        if user.password == password:
            serializer = UserSerializer(user)
            # 这里可能需要替换为你实际使用的 JWT 相关代码
            # 定义有效期为 1 小时
            expiration_time = datetime.utcnow() + timedelta(hours=1)
            # 构造 Payload
            payload = {
                'user_id': user.id,
                'exp': expiration_time  # 设置过期时间
            }
            # payload = jwt_payload_handler(user)
            token = jwt.encode(payload, 'secret_key', algorithm='HS256')
            return Response({'success': '登录成功', 'user': serializer.data, 'token': token})
        else:
            return Response({'error': '用户名或密码错误'}, status=400)
    else:
        return Response({'error': '不存在该用户'}, status=400)


@api_view(['POST'])
def createView(request):
    username = request.data.get('username')  # 使用 request.data 获取 POST 数据
    password = request.data.get('password')
    try:
        user = User.objects.get(username=username)
        return Response({'msg': '已存在该用户'})
    except User.DoesNotExist:
        user = User.objects.create(username=username, password=password)
        user.save()
        return Response({'msg': 'True'})

@api_view(['POST'])
def searchView(request):
    authorization_header = request.headers.get('Authorization')
    if authorization_header:
        token = authorization_header.split(' ')[1]  # 获取 Bearer 后的 token
        # 进行 token 验证和处理
        if token != None:
            # 获取分页参数
            page = int(request.data.get('page', 1))  # 默认为第一页
            page_size = int(request.data.get('page_size', 10))  # 默认每页显示 10 条数据
            searchKeyword = request.data.get('searchKeyword')
            # 定义查询集
            redis = RedisUtils()
            redis.zIncrby(1,searchKeyword)
            queryset = Topic.objects.filter(Q(title__icontains=searchKeyword) | Q(content__icontains=searchKeyword))
            queryset2 = Car.objects.filter(Q(manufacturers=searchKeyword) | Q(carname = searchKeyword)).distinct()
            aboutuser = User.objects.filter(webname=searchKeyword)
            # 手动进行分页
            start_index = (page - 1) * page_size
            end_index = start_index + page_size
            paginated_data = queryset[start_index:end_index]
            # 实例化序列化器并序列化分页后的结果
            topic_serializer = TopicSerializer(paginated_data, many=True)
            car_serializer = CarSerializer(queryset2, many=True)
            user_serializer = UserSerializer(aboutuser, many=True)

            return Response({'topicmsg':topic_serializer.data,'total':len(queryset),'carmsg':car_serializer.data,'aboutuser':user_serializer.data})
        else:
            return Response({'error': '非法token'}, status=400)
    else:
        return Response({'error': '未找到token字段'}, status=400)

@api_view(['POST'])
def topic_details(request):
    if 'token' in request.data:
        try:
            topic_id = request.data['topicid']  # 话题id
            topic = Topic.objects.get(id=topic_id)
            comments = Comment.objects.filter(topic_id=topic_id)
            commentserializer = TopiccommentSerializer(comments, many=True)
            topicserializer = TopicSerializer(topic)
            # 话题推荐
            topic_recommender = TopicRecommender()
            recommended_topics = topic_recommender.recommend_topics_for_user(topic)
            recommended_topic = [TopicSerializer_2(topic).data for topic in recommended_topics]
            # 用户推荐
            return Response({'topic': topicserializer.data, 'comments': commentserializer.data, 'recommended_topic': recommended_topic})
        except jwt.ExpiredSignatureError:
            return Response({'msg': 'Token已过期'}, status=400)
        except jwt.DecodeError:
            return Response({'msg': '无法解析Token'}, status=400)
    else:
        return Response({'msg': '未找到token字段'}, status=400)

@csrf_exempt
def delete_usertopic(request, pk):
    topic = get_object_or_404(Topic, pk=pk)
    # 执行删除操作
    topic.delete()
    # 返回成功的响应
    return JsonResponse({'message': 'Topic deleted successfully.'})
@api_view(['POST'])
def delete_usercollect(request):
    try:
        # 获取token并检查是否存在
        token = request.data.get('token')
        id = request.data.get('id')
        print(id)
        if not token:
            return JsonResponse({'message': '登录已过期，请重新登录'}, status=400)
        # 解码token，并提取用户ID
        decoded_token = jwt.decode(token, options={"verify_signature": False})
        user_id = decoded_token.get('user_id')
        # 获取当前用户和要收藏的话题
        user = User.objects.get(id=user_id)
        user.collect.remove(id)
        return JsonResponse({'message': '取消成功'})
    except ExpiredSignatureError:
        return JsonResponse({'message': 'Topic deleted successfully'})




@csrf_exempt
def vote_up_topic(request, pk):
    # 获取要点赞的话题对象
    topic = get_object_or_404(Topic, pk=pk)
    # 执行点赞操作，这里假设你的 Topic 模型有一个 vote_up 方法来进行点赞
    topic.vote_up()  # 假设你的 Topic 模型有一个 vote_up 方法来进行点赞
    # 返回 JSON 响应，通知前端点赞成功
    return JsonResponse({'message': 'Topic voted up successfully.'})

@csrf_exempt
def confirm_delete_usertopic(request):
    data = json.loads(request.body)
    token = data.get('token')
    # 解码token，并提取用户ID
    decoded_token = jwt.decode(token, options={"verify_signature": False})
    id = data.get('id')
    user_id = decoded_token.get('user_id')
    user = User.objects.get(pk=user_id)
    user2 = User.objects.get(pk=id)
    # 获取要取消关注的用户对象
    user.concern.remove(user2)
    # 从当前用户的关注列表中移除该用户
    return JsonResponse({'message': '取消成功'})  # 假设重定向到用户的个人资料页面

@csrf_exempt
def vote_down_topic(request,pk):
    # 获取要点赞的话题对象
    topic = get_object_or_404(Topic, pk=pk)
    # 执行点赞操作，这里假设你的 Topic 模型有一个 vote_up 方法来进行点赞
    topic.vote_down()  # 假设你的 Topic 模型有一个 vote_up 方法来进行点赞

    # 返回 JSON 响应，通知前端点赞成功
    return JsonResponse({'message': 'Topic voted down successfully.'})

@api_view(['POST'])
def collect_topic(request):
    try:
        # 获取token并检查是否存在
        token = request.data.get('token')
        if not token:
            return JsonResponse({'message': '登录已过期，请重新登录'}, status=400)
        # 解码token，并提取用户ID
        decoded_token = jwt.decode(token, options={"verify_signature": False})
        user_id = decoded_token.get('user_id')
        # 获取当前用户和要收藏的话题
        user = User.objects.get(id=user_id)
        topic_id = request.data.get('topic_id')
        topic = Topic.objects.get(id=topic_id)
        # 检查用户是否已经收藏过该话题
        if user.collect.filter(id=topic_id).exists():
            return JsonResponse({'message': '请勿重复收藏'})
        # 将话题添加到用户的收藏列表中
        user.collect.add(topic)
        return JsonResponse({'message': '收藏成功'})

    except ExpiredSignatureError:
        return JsonResponse({'message': 'Token has expired'}, status=401)


@csrf_exempt
def submit_comment(request):
    if request.method == 'POST':
        # 解析请求数据
        data = json.loads(request.body)
        topic_id = data.get('topic_id')
        content = data.get('content')
        token = data.get('token')
        token_bytes = token.encode()
        decoded_token = jwt.decode(token_bytes, options={"verify_signature": False})
        user_id = decoded_token.get('user_id')
        # 创建新的评论对象并保存到数据库
        try:
           Comment.objects.create(
                topic_id=topic_id,
                user_id=user_id,
                content=content
            )
        except Exception as e:
            return JsonResponse({'error': str(e)}, status=500)
        # 返回成功响应
        return JsonResponse({'message': 'Comment submitted successfully.'}, status=201)
    else:
        # 如果请求方法不是POST，则返回405方法不允许的响应
        return JsonResponse({'error': 'Method Not Allowed'}, status=405)

@api_view(['POST'])
def concern(request):
    try:
        data = get_top_liked_users()
        serializer = UserSerializer2(data, many=True)
        return Response({'concern': serializer.data})
    except Exception as e:
        return Response({'error': str(e)})


@api_view(['POST'])
def submitForm(request):
    try:
        # 获取token并检查是否存在
        token = request.data.get('token')
        if not token:
            return JsonResponse({'message': '登录已过期，请重新登录'}, status=401)
        # 解码token，并提取用户ID
        decoded_token = jwt.decode(token, options={"verify_signature": False})
        user_id = decoded_token.get('user_id')
        # 获取当前用户和要修改的个人信息
        user = User.objects.get(id=user_id)
        usermsg = request.data.get('usermsg')
        # 更新用户信息
        user.webname = usermsg.get('webname', user.webname)
        user.tel = usermsg.get('tel', user.tel)
        # 检查日期字段是否存在且非空
        user.birthday = request.data.get('birthday')
        user.email = usermsg.get('email', user.email)
        user.address = usermsg.get('address', user.address)
        user.save()
        return JsonResponse({'message': '修改个人信息成功'})
    except ExpiredSignatureError:
        return JsonResponse({'message': '登录已过期，请重新登录'}, status=401)
    except User.DoesNotExist:
        return JsonResponse({'message': '用户不存在'}, status=404)
    except ValidationError as e:
        # 返回具体的字段错误消息
        return JsonResponse({'message': e.detail}, status=400)
    except Exception as e:
        # 返回其他异常消息
        return JsonResponse({'message': str(e)}, status=400)


@api_view(['POST'])
def user_addtopic(request):
    try:
        # 获取token并解码
        token = request.data.get('token')  # 注意：这里假设您是通过POST请求发送token的
        decoded_token = jwt.decode(token, options={"verify_signature": False})
        user_id = decoded_token.get('user_id')
        if request.method == 'POST':
            # 获取表单数据
            title = request.data.get('title')
            topic_type = request.data.get('topic_type')
            topic_content = request.data.get('topic_content')
            print(title, topic_type, topic_content)
            # 创建话题对象并保存到数据库
            Topic.objects.create(
                title=title,
                topic_type=topic_type,
                content=topic_content,
                publisher_id=user_id  # 假设您的话题模型有一个名为user_id的外键字段来关联用户
            )
            # 返回成功响应
            return JsonResponse({'message': '话题发布成功'})
        else:
            # 如果请求不是POST方法，返回错误响应
            return JsonResponse({'error': '仅支持POST请求'})
    except Exception as e:
        # 返回其他异常消息
        return JsonResponse({'message': str(e)})


@api_view(['POST'])
def getotherusermsg(request):
    try:
        user_id = request.data['user_id']  # 用户id
        print(user_id)
        user = User.objects.get(id=user_id)
        topic = Topic.objects.filter(publisher_id = user_id)
        user_serializer = UserSerializer2(user)
        topic_serializer = TopicSerializer(topic, many=True)
        return Response({'usermsg': user_serializer.data,'topicmsg':topic_serializer.data})
    except Exception as e:
        # 返回其他异常消息
        return JsonResponse({'message': str(e)})



